/**
 * Created with IntelliJ IDEA.
 * User: farhad
 * Date: 11/2/14
 * Time: 12:38 AM
 * To change this template use File | Settings | File Templates.
 */
/*
 * jQuery Expander plugin
 * Version 0.3.1  (12/09/2008)
 * @requires jQuery v1.1.1+
 *
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */


(function($) {

    $.fn.expander = function(options) {

        var opts = $.extend({}, $.fn.expander.defaults, options);
        var delayedCollapse;
        return this.each(function() {
            var $this = $(this);
            var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
            var cleanedTag, startTags, endTags;
            var allText = $this.html();
            var startText = allText.slice(0, o.slicePoint).replace(/\w+$/,'');
            startTags = startText.match(/<\w[^>]*>/g);
            if (startTags) {startText = allText.slice(0,o.slicePoint + startTags.join('').length).replace(/\w+$/,'');}

            if (startText.lastIndexOf('<') > startText.lastIndexOf('>') ) {
                startText = startText.slice(0,startText.lastIndexOf('<'));
            }
            var endText = allText.slice(startText.length);
            // create necessary expand/collapse elements if they don't already exist
            if (!$('span.details', this).length) {
                // end script if text length isn't long enough.
                if ( endText.replace(/\s+$/,'').split(' ').length < o.widow ) { return; }
                // otherwise, continue...
                if (endText.indexOf('</') > -1) {
                    endTags = endText.match(/<(\/)?[^>]*>/g);
                    for (var i=0; i < endTags.length; i++) {

                        if (endTags[i].indexOf('</') > -1) {
                            var startTag, startTagExists = false;
                            for (var j=0; j < i; j++) {
                                startTag = endTags[j].slice(0, endTags[j].indexOf(' ')).replace(/(\w)$/,'$1>');
                                if (startTag == rSlash(endTags[i])) {
                                    startTagExists = true;
                                }
                            }
                            if (!startTagExists) {
                                startText = startText + endTags[i];
                                var matched = false;
                                for (var s=startTags.length - 1; s >= 0; s--) {
                                    if (startTags[s].slice(0, startTags[s].indexOf(' ')).replace(/(\w)$/,'$1>') == rSlash(endTags[i])
                                        && matched == false) {
                                        cleanedTag = cleanedTag ? startTags[s] + cleanedTag : startTags[s];
                                        matched = true;
                                    }
                                };
                            }
                        }
                    }

                    endText = cleanedTag && cleanedTag + endText || endText;
                }
                $this.html([
                    startText,
                    '<span class="read-more">',
                    o.expandPrefix,
                    '<a href="#">',
                    o.expandText,
                    '</a>',
                    '</span>',
                    '<span class="details">',
                    endText,
                    '</span>'
                ].join('')
                );
            }
            $this
                .find('span.details').hide()
                .end()
                .find('span.read-more a').click(function() {

                    $(this).parent().hide()
                        .next('span.details')[o.expandEffect](o.expandSpeed, function() {
                        var $details = $(this);
                        $details.css({zoom: ''});
                        if (o.collapseTimer) {
                            delayedCollapse = setTimeout(function() {
                                    reCollapse($details);
                                },
                                o.collapseTimer
                            );

                        }
                    });

                    return false;
                });
            if (o.userCollapse) {
                $this
                    .find('span.details').append('<span class="re-collapse">' + o.userCollapsePrefix + '<a href="#">' + o.userCollapseText + '</a></span>');
                $this.find('span.re-collapse a').click(function() {

                    clearTimeout(delayedCollapse);
                    var $detailsCollapsed = $(this).parents('span.details');
                    reCollapse($detailsCollapsed);
                    return false;
                });
            }

        });
        function reCollapse(el) {
            el.hide()
                .prev('span.read-more').show();
        }
        function rSlash(rString) {
            return rString.replace(/\//,'');
        }
    };
    // plugin defaults
    $.fn.expander.defaults = {
        slicePoint:       100,  // the number of characters at which the contents will be sliced into two parts.
        // Note: any tag names in the HTML that appear inside the sliced element before
        // the slicePoint will be counted along with the text characters.
        widow:            4,  // a threshold of sorts for whether to initially hide/collapse part of the element's contents.
        // If after slicing the contents in two there are fewer words in the second part than
        // the value set by widow, we won't bother hiding/collapsing anything.
        expandText:       'read more', // text displayed in a link instead of the hidden part of the element.
        // clicking this will expand/show the hidden/collapsed text
        expandPrefix:     '&hellip; ',
        collapseTimer:    0, // number of milliseconds after text has been expanded at which to collapse the text again
        expandEffect:     'fadeIn',
        expandSpeed:      '',   // speed in milliseconds of the animation effect for expanding the text
        userCollapse:     true, // allow the user to re-collapse the expanded text.
        userCollapseText: '[collapse expanded text]',  // text to use for the link to re-collapse the text
        userCollapsePrefix: ' '
    };
})(jQuery);
